package com.net.interceptors

import android.util.Log
import okhttp3.Interceptor
import okhttp3.MediaType
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody
import okhttp3.ResponseBody.Companion.toResponseBody
import okio.Buffer

/**
 * @describe:
 * @Author: lixiaopeng
 * @Date: 2020/6/24
 */
class LoggerInterceptor(val tag: String? = "net") : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        logRequest(request)
        val response = chain.proceed(request)
        return logResponse(response)
    }

    /**
     * 打印请求结果
     */
    private fun logResponse(response: Response):Response {
        var resultResponse:Response = response
        try {
            val clone = response.newBuilder().build()
            val url = clone.request.url.toString()
            val body = clone.body

            var bodyStr = ""
            if (body!=null){
                val contentType = body.contentType()
                if (contentType==null){
                    bodyStr = "无法识别内容信息"
                }else if(isText(contentType)){
                    bodyStr = body.string()
                    //body.string()方法调用后会关闭流，所以copy一个，执行后续操作
                    val tempBody = bodyStr.toResponseBody(contentType)
                    resultResponse = response.newBuilder().body(tempBody).build()
                }else{
                    bodyStr = "返回为文件"
                }
            }
            val logStr = StringBuilder()
                    .append("==========response log===========")
                    .append("\n\t $url")
                    .append("\n\t $bodyStr").toString()
            Log.d(tag, logStr)
        }catch (e:Exception){
            Log.w(tag, "返回日志打印异常")
        }

        return resultResponse
    }

    /**
     * 打印请求参数
     */
    private fun logRequest(request: Request) {
        try {
            val url = request.url.toString()
            val method = request.method
            val headers = request.headers.toString()
            var bodyStr: String = bodyToStr(request)
            val logStr = StringBuilder()
                    .append("==========request log===========")
                    .append("\n\t $url")
                    .append("\n\t $method")
                    .append("\n\t $headers")
                    .append("\n\t $bodyStr").toString()
            Log.d(tag, logStr)
        } catch (e: Exception) {
            Log.w(tag, "请求日志打印异常")
        }
    }

    private fun bodyToStr(request: Request): String {
        return try {
            val build = request.newBuilder().build()
            val buffer = Buffer()
            build.body?.writeTo(buffer)
            buffer.readUtf8()
        } catch (e: Exception) {
            "request body show err."
        }
    }

    private fun isText(mediaType: MediaType?): Boolean {
        if (mediaType?.type != null && mediaType.type == "text") {
            return true
        }
        if (mediaType?.subtype != null) {
            if (mediaType.subtype == "x-www-form-urlencoded" || mediaType.subtype == "json" || mediaType.subtype == "xml" || mediaType.subtype == "html" || mediaType.subtype == "webviewhtml") return true
        }
        return false
    }

}